home *** CD-ROM | disk | FTP | other *** search
- unit IFF;
-
- interface
-
- uses Objects, S32K;
-
- procedure ShowIFF(F: PStream);
-
- implementation
-
- uses CRT;
-
- type BMPHeader = record
- BW, BH: Word;
- PX, PY: Integer;
- NP: Byte;
- Mask: Byte;
- Comp: Byte;
- Flags: Byte;
- TC: Word;
- XA, YA: Byte;
- PW, PH: Word;
- end;
-
- RGBSet = record
- R: Byte;
- G: Byte;
- B: Byte;
- end;
-
- TRGBPal = Array[0..0] of RGBSet;
- PRGBPal = ^TRGBPal;
-
- const Odd: Byte = 0;
-
- var BMPHdr: BMPHeader;
- Comment: String;
- Palette: PRGBPal;
- PalCols: Word;
- Mode: LongInt;
-
- procedure SwapBytes(var Val: LongInt); assembler;
- asm
- LES DI, Val
- mov al,es:[DI]
- xchg es:[DI+3],al
- mov es:[DI], al
- mov al,es:[DI+1]
- xchg al,es:[DI+2]
- mov es:[DI+1],al
- end;
-
- function ReadBMHD(F: PStream): LongInt;
- var Len: LongInt;
- begin
- ReadBMHD := -1;
- F^.Read(Len, 4);
- SwapBytes(Len);
- if Len = 20 then
- begin
- F^.Read(BMPHdr, 20);
- with BMPHdr do
- begin
- BW := Swap(BW);
- BH := Swap(BH);
- PX := Swap(PX);
- PY := Swap(PY);
- TC := Swap(TC);
- PW := Swap(PW);
- PH := Swap(PH);
- end;
- ReadBMHD := 24;
- end;
- end;
-
- function ReadANNO(F: PStream): LongInt;
- var Len: LongInt;
- Sam: Char;
- I: Integer;
- begin
- F^.Read(Len, 4);
- SwapBytes(Len);
- Comment := '';
- F^.Read(Comment[1], Len - 1);
- Comment[0] := Chr(Len-1);
- F^.Read(Sam, 1);
- Inc(Len, 4);
- ReadANNO := Len;
- end;
-
- function ReadCMAP(F: PStream): LongInt;
- var Len: LongInt;
- Sam: Char;
- I: Integer;
- R, B, G: Byte;
- J: Integer;
- K: Integer;
- begin
- F^.Read(Len, 4);
- SwapBytes(Len);
- GetMem(Palette, Len);
- PalCols := Len div 3;
- F^.Read(Palette^, Len);
- asm
- LES DI, Palette
- MOV BX, Word(Len)
- MOV CL, 3
- @@1:
- SHR BYTE PTR ES:[DI], CL
- INC DI
- DEC BX
- JNZ @@1
- end;
- Inc(Len, 4);
- ReadCMAP := Len;
-
- Mode32K;
- for I := 0 to PalCols - 1 do
- begin
- R := Palette^[I].R;
- G := Palette^[I].G;
- B := Palette^[I].B;
- for J := I * 2 to I*2+1 do
- for K := 0 to 10 do
- MemW[SegA000:J*2 + K * 640 * 2] := R * 1024 + G * 32 + B;
- end;
- R := Byte(ReadKey);
- end;
-
- procedure GetPad(F: PStream);
- var S: Byte;
- begin
- if Odd = 0 then
- F^.Read(S, 1);
- Odd := 0;
- end;
-
- function GetByte(F: PStream): Byte;
- const Rept: Byte = 0;
- LChr: Byte = 0;
- Litr: Byte = 0;
- begin
- Odd := Odd xor 1;
- if BMPHdr.Comp <> 1 then
- begin
- F^.Read(Litr, 1);
- GetByte := Litr;
- exit;
- end;
- if (Rept > 0) then
- begin
- Dec(Rept);
- GetByte := LChr;
- Exit;
- end;
- if Litr > 0 then
- begin
- F^.Read(LChr, 1);
- GetByte := LChr;
- Dec(Litr);
- exit;
- end;
- repeat
- F^.Read(LChr, 1);
- until LChr <> $80;
- if LChr and $80 <> 0 then
- begin
- Rept := Not LChr + 2;
- F^.Read(LChr, 1);
- end else
- Litr := LChr + 1;
- GetByte := GetByte(F);
- end;
-
- procedure StretchPic;
- var I, J: Integer;
- FI, FJ: Integer;
- DI, DJ: Integer;
- R, G, B: Word;
- C: LongInt;
- SX, SY: LongInt;
- RX, RY: Byte;
- begin
- if BMPHdr.PH > BMPHdr.BH then
- begin
- I := BMPHdr.PH;
- FI := 0;
- DI := -1;
- end else
- begin
- I := -1;
- FI := BMPHdr.PH - 1;
- DI := 1;
- end;
- repeat
- Inc(I, DI);
- if BMPHdr.PW > BMPHdr.BW then
- begin
- J := BMPHdr.PW;
- FJ := 0;
- DJ := -1;
- end else
- begin
- J := -1;
- FJ := BMPHdr.PW - 1;
- DJ := 1;
- end;
- repeat
- Inc(J, DJ);
- SX := LongInt(BMPHdr.BW) * J;
- SX := SX div (BMPHdr.PW - 1);
- SY := LongInt(BMPHdr.BH) * I;
- SY := SY div (BMPHdr.PH - 1);
- C := LongInt(640*2)*SY + SX * 2;
- if (((C - Page) > $fffe) or ((C - Page) < 0)) then
- SetPage(C);
- R := MemW[SegA000:Word(C)];
- C := LongInt(640*2)*I + J * 2;
- if (((C - Page) > $fffe) or ((C - Page) < 0)) then
- SetPage(C);
- MemW[SegA000:Word(C)] := R;
- until J = FJ;
- until I = FI;
- end;
-
- function ShowBODY(F: PStream): LongInt;
- var Len: LongInt;
- I, J, K, L: Word;
- X: LongInt;
- Sh: Byte;
- S: Byte;
- S1, S2: Word;
- Rd, Gr, Bl: Byte;
- Ov: Word;
- begin
- F^.Read(Len, 4);
- SwapBytes(Len);
- Inc(Len, 4);
- Mode32K;
- SetPage(0);
- for I := 0 to BMPHdr.BH - 1 do
- begin
- Rd := 0; Bl := 0; Gr := 0;
- for L := 0 to BMPHdr.NP - 1 do
- begin
- X := LongInt(640*2) * I; Sh := L;
- for J := 0 to ((BMPHdr.BW + 15) div 16) * 2 - 1 do
- begin
- S := GetByte(F);
- for K := 7 downto 0 do
- begin
- if (((X - Page) > $fffe) or ((X - Page) < 0)) then
- SetPage(X);
- MemW[SegA000:Word(X)] := MemW[SegA000:Word(X)]
- or (((S shr K) and 1) shl Sh);
- if L = BMPHdr.NP - 1 then
- begin
- S1 := MemW[SegA000:Word(X)];
- S2 := S1 shr 4; if (Mode and $800 <> 0) then
- S1 := S1 and $f;
- if ((Mode and $800) <> $800) or (S2 = 0) then
- with Palette^[S1] do
- begin
- Rd := R;
- Gr := G;
- Bl := B;
- end else
- case S2 of
- 2: Rd := S1 * 2;
- 1: Bl := S1 * 2;
- 3: Gr := S1 * 2;
- end;
- Ov := Rd * 1024 + Gr * 32 + Bl;
- MemW[SegA000:Word(X)] := Ov;
- end;
- Inc(X, 2);
- end;
- end;
- end;
- end;
-
- StretchPic;
-
- S := Ord(ReadKey);
- ShowBody := Len;
- end;
-
- function ReadCAMG(F: PStream): LongInt;
- var Len: LongInt;
- begin
- F^.Read(Len, 4);
- SwapBytes(Len);
- F^.Read(Mode, 4);
- SwapBytes(Mode);
- Inc(Len, 4);
- ReadCAMG := Len;
- end;
-
- function ReadILBM(F: PStream): LongInt;
- var ID: LongInt;
- Len: LongInt;
- Dum: Array[0..7] of byte;
- begin
- Len := 0;
- repeat
- F^.Read(ID, 4);
- Inc(Len, 4);
- if ID = $44484D42 then Inc(Len, ReadBMHD(F)) else
- if ID = $4F4E4E41 then Inc(Len, ReadANNO(F)) else
- if ID = $50414D43 then Inc(Len, ReadCMAP(F)) else
- if ID = $474D4143 then Inc(Len, ReadCAMG(F)) else
- if ID = $20495044 then begin F^.Read(Dum, 8); Inc(Len, 8); end else
- if ID = $59444F42 then Inc(Len, ShowBODY(F));
- until ID = 0;
- ReadILBM := Len;
- end;
-
- procedure ReadData(F:PStream);
- var Len: LongInt;
- ID: LongInt;
- begin
- F^.Read(Len, 4);
- SwapBytes(Len);
- while (Len > 0) do
- begin
- F^.Read(ID, 4);
- Dec(Len, 4);
- if ID = $4D424C49 then Dec(Len, ReadILBM(F));
- end;
- end;
-
- procedure ShowIFF(F: PStream);
- var ID: LongInt;
- begin
- F^.Read(ID, 4);
- if ID = $4D524F46 then
- ReadData(F);
- end;
-
- end.